package com.ruoyi.common.integrate.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.integrate.constant.WxConstant;
import com.ruoyi.common.integrate.domain.Department;
import com.ruoyi.common.integrate.domain.DeptUser;
import com.ruoyi.common.integrate.domain.User;
import com.ruoyi.common.utils.StringUtils;
import org.apache.commons.httpclient.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: MMDZ
 * @Desc: TODO 集成企业微信服务
 */
@Component
public class QYWeiXinService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CommonService commonService;
    @Autowired
    private RedisCache redisCache;

    //企业id
    @Value("${qyweixin.corpid}")
    private String corpid;
    //代办中心id
    @Value("${qyweixin.centerid}")
    private String centerid;

    //报工secret
    @Value("${qyweixin.secret.work}")
    private String workSecret;
    //通讯录管理secret
    @Value("${qyweixin.secret.contact}")
    private String contactSecret;
    //代办中心secret
    @Value("${qyweixin.secret.center}")
    private String centerSecret;

    private final String workSecretKey = "work_access_token";//报工的 redis缓存的key
    private final String contactSecretKey = "contact_access_token";//通讯录管理的 redis缓存的key
    private final String centerSecretKey = "center_access_token";//代办中心的 redis缓存的key

    /**
     * 企业微信 发送应用消息
     * @param userId 发送的用户id，其实就是企业微信的用户邮箱
     * @param content 发送内容
     * @return
     */
    public String wxSend(String userId, String content) {
        logger.info("API 获取企业微信发送消息！！！");
        Map<String, Object> map = new HashMap<>(5);
        map.put("touser", userId);
        map.put("totag", "测试发消息");
        map.put("msgtype", "text");
        map.put("agentid", centerid);
        Map<String, Object> contentMap = new HashMap<>(1);
        contentMap.put("content", content);
        map.put("text", contentMap);

        String accessToken = getAccessTokenByRedis(centerSecretKey, centerSecret);
        String url = String.format(WxConstant.WX_SEND_MESSAGE, accessToken);
        String data = commonService.sendPost(url, JSON.toJSONString(map));
        return data;
    }

    /**
     * 获取 企业微信 成员列表
     *
     * @return
     */
    public List<User> getUserByQYWeiXin() {
        logger.info("API 获取企业微信成员列表");
        String accessToken = getAccessTokenByRedis(contactSecretKey, contactSecret);
        String url = String.format(WxConstant.WX_USER_LIST_URL, accessToken, 1, 1);
        String res = commonService.sendGet(url);
        logger.info("返回信息为{}", res);
        JSONObject jsonRlt = JSON.parseObject(res);
        Integer errCode = jsonRlt.getInteger("errcode");
        List<User> userList = null;
        if (0 == errCode) {
            String userStr = jsonRlt.getString("userlist");
            userList = JSON.parseArray(userStr, User.class);
        }
        return userList;
    }

    /**
     * 获取 企业微信 部门成员详情
     *
     * @return
     */
    public List<DeptUser> getDeptUserByQYWeiXin(String deptId) {
        logger.info("API 获取企业微信部门成员详情");
        String accessToken = getAccessTokenByRedis(contactSecretKey, contactSecret);
        String url = String.format(WxConstant.WX_DEPT_USER_LIST_URL, accessToken, deptId);
        String res = commonService.sendGet(url);
        logger.info("返回信息为{}", res);
        JSONObject jsonRlt = JSON.parseObject(res);
        Integer errCode = jsonRlt.getInteger("errcode");
        List<DeptUser> deptUserList = null;
        if (0 == errCode) {
            String userStr = jsonRlt.getString("userlist");
            deptUserList = JSON.parseArray(userStr, DeptUser.class);
        }
        return deptUserList;
    }

    /**
     * 获取 企业微信 部门列表
     *
     * @return
     */
    public List<Department> getDeptByQYWeiXin() {
        logger.info("API 获取企业微信部门列表");
        String accessToken = getAccessTokenByRedis(contactSecretKey, contactSecret);
        String url = String.format(WxConstant.WX_DEPT_LIST_URL, accessToken);
        String res = commonService.sendGet(url);
        logger.info("返回信息为{}", res);
        JSONObject jsonRlt = JSON.parseObject(res);
        Integer errCode = jsonRlt.getInteger("errcode");
        List<Department> departmentList = null;
        if (0 == errCode) {
            String departmentStr = jsonRlt.getString("department");
            departmentList = JSON.parseArray(departmentStr, Department.class);
        }
        return departmentList;
    }

    /**
     * 获取访问用户身份 --- 根据code获取成员信息 UserId
     *
     * @return UserId
     */
    public String getUserInfoByCode(String code) {
        logger.info("API 根据code获取成员信息");
        String accessToken = getAccessTokenByRedis(workSecretKey, workSecret);
        String url = String.format(WxConstant.WX_USER_INFO_BY_CODE_URL, accessToken, code);
        String res = commonService.sendGet(url);
        logger.info("返回信息为{}", res);
        JSONObject jsonRlt = JSON.parseObject(res);
        Integer errCode = jsonRlt.getInteger("errcode");
        String userId = null;
        if (0 == errCode) {
            userId = jsonRlt.getString("UserId");
        }
        return userId;
    }

    /**
     * 在Redis中获取 accessToken
     *
     * @param secretKey
     * @param secret
     * @return
     */
    private String getAccessTokenByRedis(String secretKey, String secret) {
        logger.info("在Redis中获取accessToken");
        String accessToken = redisCache.getCacheObject(secretKey);
        boolean isExpire = redisCache.isExpire(secretKey);
        if (StringUtils.isEmpty(accessToken) || isExpire) {
            accessToken = getAccessToken(secretKey, secret);
            if (Objects.isNull(accessToken))
                throw new ServiceException("获取企业微信令牌异常", HttpStatus.SC_INTERNAL_SERVER_ERROR);
        }
        return accessToken;
    }

    /**
     * 获取应用的 access_token (每个应用的access_token不同)
     *
     * @param secretKey 缓存redis的 secretKey
     * @param secret    企业微信 应用的secret（秘钥）
     * @return
     */
    private String getAccessToken(String secretKey, String secret) {
        logger.info("API获取应用的 access_token");
        String url = String.format(WxConstant.WX_ACCESS_TOKEN_URL, corpid, secret);
        String res = commonService.sendGet(url);
        JSONObject jsonRlt = JSON.parseObject(res);

        Integer errCode = jsonRlt.getInteger("errcode");
        String accessToken = null;
        if (0 == errCode) {
            accessToken = jsonRlt.getString("access_token");
            Integer expires = jsonRlt.getInteger("expires_in");
            /* 保存到redis缓存(token有效期为7200) */
            redisCache.setCacheObject(secretKey, accessToken, expires, TimeUnit.SECONDS);
        }
        return accessToken;
    }

}
